import Loading from "../../inner/Loading";
import { PropType, VNode, computed, defineComponent, ref, watch } from "vue";
import formFieldRef from "../../use/formFieldRef";

export interface SwitchProps {
    size?: 'small'|'default'|'large',
    disabled?: boolean,
    name?: string,
    labels?: any[],
    values?: any[],
    round?: boolean,
    icon?: VNode | VNode[],
    colors?: string[],
    onBeforeChange?: (currentStatus: boolean) => Promise<boolean>,
    loading?: boolean,
    modelValue?: boolean,
    asFormField?: boolean
}

export default defineComponent({
    name: 'Switch',
    props: {
        size: {
            type: String as PropType<SwitchProps['size']>
        },
        disabled: {
            type: Boolean as PropType<SwitchProps['disabled']>
        },
        name: {
            type: String as PropType<SwitchProps['name']>
        },
        modelValue: {
            type: Boolean as PropType<SwitchProps['modelValue']>
        },
        loading: {
            type: Boolean as PropType<SwitchProps['loading']>
        },
        labels: {
            type: Array as PropType<SwitchProps['labels']>
        },
        values: {
            type: Array as PropType<SwitchProps['values']>
        },
        round: {
            type: Boolean as PropType<SwitchProps['round']>, default: true
        },
        icon: {
            type: [Object, Array] as PropType<SwitchProps['icon']>
        },
        colors: {
            type: Array as PropType<SwitchProps['colors']>
        },
        asFormField: {
            type: Boolean as PropType<SwitchProps['asFormField']>, default: true
        },
        onBeforeChange: {
            type: Function as PropType<SwitchProps['onBeforeChange']>
        },
    },
    emits: ['update:modelValue', 'change'],
    setup (props: SwitchProps, { emit }) {
        const checked = formFieldRef(props, emit, props.modelValue ?? false);

        const classList = computed(() => ({
            'cm-switch': true,
            [`cm-switch-${props.size}`]: props.size,
            'cm-switch-disabled': props.disabled,
            'cm-switch-checked': checked.value,
            'cm-switch-loading': props.loading,
            'cm-switch-round': props.round ?? true,
        }));

        watch(() => props.modelValue, (value) => {
            checked.value = value;
        });

        const style = computed(() => ({
            '--cm-switch-default-color': props.colors && props.colors[0],
            '--cm-switch-active-color': props.colors && props.colors[1],
        }));

        const labels = props.labels || [];
        const values = props.values || [true, false];

        const toggleSwitch = async () => {
            if (props.disabled) {
                return;
            }
            if (props.loading) {
                return;
            }
            let ret = true;
            if (props.onBeforeChange) {
                ret = await props.onBeforeChange(checked.value);
            }
            if (ret) {
                const flag = !checked.value;
                const v = flag ? values[0] : values[1];
                emit('change', v);
                checked.value = flag;
                emit('update:modelValue', flag);
            }
        };

        const icon = computed(() => {
            if (checked.value) {
                if (props.icon && props.icon instanceof Array) {
                    return props.icon[1];
                }
                return props.icon;
            } else {
                if (props.icon && props.icon instanceof Array) {
                    return props.icon[0];
                }
                return props.icon;
            }
        });

        return () => <div class={classList.value} style={style.value} tab-index="0" onClick={toggleSwitch}>
            {/* 文字对齐辅助 */}
            <span style={{width: '0px', "font-size": '12px', visibility: 'hidden'}}>A</span>
            <span class="cm-switch-inner-placeholder">
                <span><span class="cm-switch-inner-button-placeholder" />{labels[0]}</span>
                <span><span class="cm-switch-inner-button-placeholder" />{labels[1]}</span>
            </span>
            <span class="cm-switch-inner">
                {
                    icon.value ? <span class="cm-switch-inner-icon">{icon.value}</span> : null
                }
                <span class="cm-switch-label cm-switch-label-left">{labels[0]}</span>
                <span class="cm-switch-label cm-switch-label-right">{labels[1]}</span>
            </span>
            {
                props.loading ? <Loading /> : null
            }
            <input name={props.name} type="hidden" value={checked.value ? values[0] : values[1]} />
        </div>;
    }
});
